﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ElevatorDispatching
{

    /// <summary>
    /// 电梯调度系统的默认实现
    /// </summary>
    public class ElevatorDispatcher : IElevatorDispatcher
    {
        /// <summary>
        /// 系统关联的所有楼层
        /// </summary>
        public IFloorGroup Floors { get; }

        /// <summary>
        /// 系统控制的所有电梯轿厢
        /// </summary>
        public IElevatorGroup Elevators { get; } = new ElevatorGroup();

        /// <summary>
        /// 呼层呼梯信号处理程序
        /// </summary>
        private ISignalHandler _handler;

        public ElevatorDispatcher(
            IFloorGroupBuilder floorGroupBuilder, int elevatorCount = 1)
        {
            Floors = floorGroupBuilder.Build();

            for (int i = 0; i < elevatorCount; i++)
            {
                var elevator = new Elevator(i, Floors, BaseFloor);
                elevator.CallCageSignalsHandled += ElevatorCallCageSignalsHandled;
                Elevators.Add(elevator);
            }

            _handler = new DefaultMultiCageSignalHandler(Floors, Elevators);
        }

        private void ElevatorCallCageSignalsHandled(object sender, CallCageSignalsHandledEventArgs e)
        {
            switch (e.Direction)
            {
                case Direction.Up:
                    Floors[e.FloorId].CallUpButton.Reset();
                    break;
                case Direction.Down:
                    Floors[e.FloorId].CallDownButton.Reset();
                    break;
            }
            _handler.EraseCallCageSignals(e.FloorId, e.Direction);
        }

        /// <summary>
        /// 电梯系统的基站楼层
        /// </summary>
        public Floor BaseFloor => Floors.Min();

        /// <summary>
        /// 响应呼层呼梯信号，所有信号直接转发到 <see cref="ISignalHandler"/> 的一个实例。
        /// </summary>
        /// <param name="signal">呼层呼梯信号</param>
        /// <returns>指示信号是否被处理</returns>
        public bool HandleCallSignal(ICallSignal signal) => _handler.HandleCallSignal(signal);
    }
}
